<?php

namespace addons\gs_developer\controller;

use addons\gs_developer\model\Addons\AddonsModel;
use addons\gs_developer\model\CrudModel;
use app\common\controller\AddonsController;
use hiduoke\services\FormBuilder as Form;
use think\facade\Db;
use think\helper\Str;
use Yurun\SqlDiff\SqlDiff;

class Crud extends AddonsController
{
    public $prefix;
    public $err = '';
    // 表格参数
    public $tableAttrs = ['width', 'label', 'render', 'sortable', 'slotName', 'component', 'operator', 'comSearchRender', 'comSearchLabel', 'operatorPlaceholder', 'prop', 'comSearchProp', 'type'];
    // 表单参数
    public $formAttrs = ['required', 'help', 'validate', 'message', 'Title', 'type', 'render'];

    private CrudModel $model;

    protected function initialize()
    {
        parent::initialize(); // TODO: Change the autogenerated stub
        $this->prefix = config('database.connections.mysql.prefix');
        $this->model = new CrudModel();
    }


    public function index()
    {
        // 获取列表数据
        $res = $this->model->getPageList();
        return $this->success($res['count'], $res['data']);
    }


    public function getForm($id = 0)
    {
        $rule = array();
        $row = $this->model->findOrEmpty($id);//创建表单
        $form = Form::createForm("/gs_developer/crud/save?id=" . $id)->setMethod("POST");
        $rule[] = Form::input('remark', '备注', $row['remark'] ?? '')->required();
        $title = !$id ? "新增" : "编辑";
        $form->setTitle($title)->setRule($rule);
        return $this->success("", Form::getFormData($form));
    }

    public function getById($id)
    {
        $res = $this->model->where(['id' => $id])->find()->toArray();
        foreach ($res['design_data']['fieldItems'] as $key => $value) {
            $res['design_data']['fieldItems'][$key]['form']['edit'] = '1';
            $res['design_data']['fieldItems'][$key]['table']['edit'] = '1';
        }
        return $this->success('', $res);
    }

    public function save($id = 0)
    {
        $row = $this->model->findOrEmpty($id);
        $formData = getFormData();
        $row->save($formData);
        return $this->success("保存成功");
    }

    public function delete($id)
    {
        $this->model->where('id', $id)->delete();
        return $this->success('删除成功');
    }

    // 获取远程连接配置所需要的下拉选项
    public function getRemoteOptions()
    {
        $addon_name = input('addon_name', '');
    }


    /**
     * 获取远程表下拉数据
     * Create by :  刘泓宾<514660094@qq.com>
     */
    public function getRemoteTableOption()
    {
        $addon_name = input('addon_name');
        if (!$addon_name) {
            return $this->success();
        }
        // 定义表名前缀规则
        $tablePrefix = $this->prefix . $addon_name . '_';
        $tables = Db::query("SELECT TABLE_NAME AS table_name, 
                                      TABLE_COMMENT AS table_comment 
                               FROM information_schema.TABLES 
                               WHERE TABLE_SCHEMA = DATABASE() 
                               AND TABLE_NAME LIKE ?", [$tablePrefix . '%']);
        // 将结果整理为下拉选项格式
        $options = array_map(function ($item) use ($tablePrefix) {
            $label = str_replace($tablePrefix, '', $item['table_name']) . (!empty($item['table_comment']) ? ' - ' . $item['table_comment'] : ' - 无注释');
            return [
                'label' => $label,
                'value' => $item['table_name'],
            ];
        }, $tables);
        return $this->success($tables, $options);
    }

    /**
     * 根据表名返回对应的表的数据信息
     * Create by : 刘泓宾 <514660094@qq.com>
     */
    public function getRemoteFieldOption()
    {
        // 获取表名参数
        $table_name = input('table_name');
        $addon_name = input('addon_name');
        if (empty($table_name)) {
            return $this->error('缺少表名');
        }
        try {
            // 使用thinkphp的db类进行查询，获取表字段信息
            $columns = DB::query("SELECT COLUMN_NAME AS field,
                                       DATA_TYPE AS type,
                                       CHARACTER_MAXIMUM_LENGTH AS length,
                                       IS_NULLABLE AS is_null,
                                       COLUMN_DEFAULT AS default_value,
                                       COLUMN_COMMENT AS comment 
                                FROM information_schema.COLUMNS 
                                WHERE TABLE_SCHEMA = DATABASE() 
                                AND TABLE_NAME = ?", [$table_name]);
            $fieldOption = array_map(function ($item) {
                return [
                    'value' => $item['field'],
                    'label' => $item['field'] . ' - ' . ($item['comment'] ?: "无注释")
                ];
            }, $columns);
            $addon_path = "addons" . DIRECTORY_SEPARATOR . $addon_name . DIRECTORY_SEPARATOR;

            $controllerFile = $addon_path . 'controller' . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR . Str::studly(str_replace($this->prefix . $addon_name, '', $table_name)) . '.php';
            $modelFile = $addon_path . 'model' . DIRECTORY_SEPARATOR . Str::studly(str_replace($this->prefix, '', $table_name)) . ".php";

            $otherData = [
                'controllerFile'  => $controllerFile,
                'modelFile'       => $modelFile,
                'have_model'      => is_file(app()->getRootPath() . $modelFile),
                'have_controller' => is_file(app()->getRootPath() . $controllerFile),
            ];
            return $this->success('', $fieldOption, $otherData);
        } catch (\Exception $e) {
            // 错误处理
            return $this->error($e->getMessage());
        }
    }

    /**
     * 生成
     * Create by :  刘泓宾<514660094@qq.com>
     */
    public function generate()
    {
        $designData = input('designData', []);
        $fieldItems = $designData['fieldItems'];
        $table = $designData['table'];
        $aid = $designData['aid'];
        $zip = input('zip', 0);
        $addon = (new AddonsModel())->where(['id' => $aid])->find();
        // 新增表
        $create_sql = $this->create_table($fieldItems, $table, $addon);
        // 编辑表
        $update_sql = $this->update_table($fieldItems, $table, $addon);
        // 模型文件
        $model = $this->create_model_file($table, $addon, $fieldItems);
        if (!$model) {
            return $this->error($this->err);
        }
        // 控制文件
        $controller = $this->create_controller_file($table, $addon, $fieldItems);
        // 路由文件
        $router = $this->create_router_file($table, $addon);
        // api文件
        $api = $this->create_api_file($table, $addon);
        // page文件
        $page = $this->create_page_file($table, $addon, $fieldItems);

        $data = [
            'page'       => [
                'label'  => 'Vue页面文件',
                'path'   => "src/views/{$table['name']}/index.vue",
                'code'   => $page,
                'option' => 'vue',
            ],
            'api'        => [
                'label'  => 'Api文件',
                'path'   => "src/api/{$table['name']}.js",
                'code'   => $api,
                'option' => 'javascript',
            ],
            'router'     => [
                'label'  => '路由文件',
                'path'   => "src/router/crud/{$table['name']}.ts",
                'code'   => $router,
                'option' => 'javascript',
            ],
            'controller' => [
                'label'  => '控制器文件',
                'path'   => "addons/{$addon['name']}/controller/admin/" . Str::studly($table['name']) . ".php",
                'code'   => $controller,
                'option' => 'php',
            ],
            'base_model' => [
                'label'  => '基础模型文件',
                'path'   => "addons/{$addon['name']}/model/" . Str::studly($addon['name'] . 'BaseModel') . ".php",
                'code'   => $model['base_model'],
                'option' => 'php',
            ],
            'model'      => [
                'label'  => '模型文件',
                'path'   => "addons/{$addon['name']}/model/" . Str::studly($addon['name'] . '_' . $table['name']) . ".php",
                'code'   => $model['model'],
                'option' => 'php',
            ],
            'create_sql' => [
                'label'  => '创建数据表',
                'path'   => '无',
                'code'   => $create_sql,
                'option' => 'sql',
            ],
            'update_sql' => [
                'label'  => '更新数据表',
                'path'   => '无',
                'code'   => $update_sql,
                'option' => 'sql',
            ]
        ];
        if ($zip) {
            $url = $this->generateAndZipFiles($data, $addon, $table);
            return $this->success('', ['url' => $url]);
        }
        return $this->success('', $data);
    }


    /**
     * 根据提供的数据创建文件结构并打包为 ZIP 文件
     *
     * @param array $data 文件数据
     * @param array $addon 插件信息
     * @param array $table 表信息
     * @return string 返回 ZIP 文件的路径
     */
    public function generateAndZipFiles($data, $addon, $table)
    {
        // 创建目标目录
        $public_path = 'uploads/addons/gs_developer/crud/' . $addon['name'] . '/' . $table['name'];
        $targetDir = app()->getRootPath() . 'public/' . $public_path;
        if (!is_dir($targetDir)) {
            mkdir($targetDir, 0755, true);
        }
        // 写入文件
        foreach ($data as $file) {
            if ($file['path'] == '无') {
                continue;
            }
            $filePath = $targetDir . '/' . $file['path'];
            $dirPath = dirname($filePath);

            // 确保目录存在
            if (!is_dir($dirPath)) {
                mkdir($dirPath, 0755, true);
            }
            // 写入文件内容
            file_put_contents($filePath, $file['code']);
        }

        $zipFileName = $targetDir . '.zip';
        $res = Zip($targetDir, $zipFileName);
        if ($res) {
            $url = $this->request->domain() . '/' . $public_path . '.zip';
            return $url;
        } else {
            return $res;
        }
    }

//    /**
//     * 将目录添加到 ZIP 文件中
//     *
//     * @param ZipArchive $zip ZIP 档案对象
//     * @param string $folder 要添加的文件夹路径
//     * @param string $localFolder 相对路径前缀
//     */
//    protected function addDirectoryToZip(ZipArchive &$zip, $folder, $localFolder)
//    {
//        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folder));
//        foreach ($iterator as $file) {
//            if ($file->isFile()) {
//                $relativePath = substr($file->getRealPath(), strlen($folder) + 1);
//                $zip->addFile($file->getRealPath(), $localFolder . DIRECTORY_SEPARATOR . $relativePath);
//            }
//        }
//    }

    public function saveDesign()
    {
        $crud_id = input('crud_id', 0);
        $designData = input('designData', []);
        $remark = input('remark', '');
        $crud = new CrudModel();
        $crud = $crud->where('id', $crud_id)->findOrEmpty();
        if (!$crud->isEmpty()) {
            $op = "edit";
            // 编辑
            if ($remark) {
                $crud->remark = $remark;
            }
            $crud->table_name = $designData['table']['name'];
            $crud->table_comment = $designData['table']['comment'];
            $crud->design_data = $designData;
//            $crud->update_time = time();
        } else {
            $op = "add";
            // 新增
            $crud->aid = $designData['aid'];
            $crud->table_name = $designData['table']['name'];
            $crud->table_comment = $designData['table']['comment'];
            $crud->remark = $remark;
            $crud->design_data = $designData;
        }
        $crud->save();
        return $this->success('Crud设计' . ($op == 'edit' ? '编辑' : '新增') . '成功', $crud, ['op' => $op]);
    }

    public function updateSql()
    {
        $designData = input('designData', []);
        $fieldItems = $designData['fieldItems'];
        $table = $designData['table'];
        $aid = $designData['aid'];
        $addon = (new AddonsModel())->where(['id' => $aid])->find();
        // 删除后新增
        $tableName = $this->prefix . $addon['name'] . '_' . $table['name'];
        // 获取表的当前结构
        // 使用 Db::query 执行原生 SQL 查询
        $result = Db::query("SELECT COUNT(*) AS count FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?", [$tableName]);
        // 判断表是否存在
        $exists = $result && $result[0]['count'] > 0;
        if ($exists) {
            // 编辑表
            $update_sql = $this->update_table($fieldItems, $table, $addon);
            if (!$update_sql) {
                return $this->success('当前没有更新项', ['type' => 'warning']);
            }
            $this->batchSql($update_sql);
            return $this->success('表已存在，更新数据表结构');
        } else {
            // 新增表
            $create_sql = $this->create_table($fieldItems, $table, $addon);
            Db::execute($create_sql);
            return $this->success('表不存在，创建数据表');
        }
    }

    /**
     * TODO 创建控制器
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $table
     * @param $addon
     * @param $fieldItems
     * @return false|void
     */
    private function create_controller_file($table, $addon, $fieldItems)
    {
        $remote = false;
        $fun_name = '';
        $withJoinTables = '';
        $quickSearchField = '';
        $model_scope_alias_default = [];
        $setRemoteUrls = [];
        $table_filter = '';
        $table_hidden = '';
        $show_table_action = false;
        $form_filter = "";
        $controlFields = [];
        $data = [
            'addon_name'        => $addon['name'],
            'table_name'        => $table['name'],
            'comment'           => $table['comment'],
            'controller_name'   => Str::studly($table['name']),
            'class_model'       => Str::studly($addon['name'] . '_' . $table['name']),
            'controllerAttr'    => '',
            'initialize'        => '',
            'data_table_attr'   => '',// 数据表格设置
            'table_buttons'     => "",
            'controller_action' => "",
            'data_form_attr'    => ''
        ];


        foreach ($fieldItems as $key => $value) {
            // 远程搜索
            if ($value['designType'] == 'remoteSelect' || $value['designType'] == 'remoteSelects') {
                $remote = true;
                if (isset($value['remoteConfig']['modelAction']) && $value['remoteConfig']['modelAction'] != '') {
                    $data['fun_name'] = $value['remoteConfig']['modelAction'];
                } else {
                    $data['fun_name'] = str_replace($this->prefix . $addon['name'] . '_', '', $value['remoteConfig']['table']);
                }
                if ($fun_name == $data['fun_name']) {
                    $this->err = "远程字段配置配置中，字段" . $value['name'] . '的远程连接函数名' . $fun_name . '重复，请设置别名';
                    return false;
                } else {
                    $fun_name = $data['fun_name'];
                }
                $remote_table = str_replace($this->prefix . $addon['name'] . "_", "", $value['remoteConfig']['table']);
                $setRemoteUrls[$value['name']] = "/".$addon['name'] . "/admin." . $remote_table . "?label={$value['remoteConfig']['label']}&val={$value['remoteConfig']['value']}";
                if (isset($value['remoteConfig']['modelAction']) && $value['remoteConfig']['modelAction']) {
                    $remote_table = $value['remoteConfig']['modelAction'];
                }
                if ($value['designType'] == 'remoteSelect') {
                    # 转为驼峰
                    $data['fun_name'] = Str::camel($data['fun_name']);
                    $remote_table = Str::camel($remote_table);
                    $withJoinTables .= "'{$data['fun_name']}',";
                    $value['table']['prop'] = $remote_table . "." . $value['remoteConfig']['label'];
                } else {
                    $value['table']['prop'] = $remote_table . "_" . $value['remoteConfig']['label'] . 's';
                }
                $label = $this->getCommentByTableName($value['remoteConfig']['table'], $value['remoteConfig']['label']);
                $value['table']['label'] = (isset($value['table']['label']) && $value['table']['label']) ? $value['table']['label'] : $label;
                $value['table']['comSearchProp'] = $value['name'];
                $value['form']['Title'] = (isset($value['form']['Title']) && $value['form']['Title']) ? $value['form']['Title'] : $label;
            }
            // 判断是否存在plaid和appid
            if ($value['name'] == "appid" || $value['name'] == "plaid") {
                $model_scope_alias_default[] = $value['name'];
            }
            // 设置过滤的表格字段
            if (isset($value['table']['filter']) && $value['table']['filter']) {
                $table_filter .= "\"{$value['name']}\",";
            }
            // 设置隐藏的表格字段
            if (isset($value['table']['hidden']) && $value['table']['hidden']) {
                $table_hidden .= "\"{$value['name']}\",";
            }

            // 创建setField内容
            $data['data_table_attr'] .= $this->create_set_field_attr($value, $this->tableAttrs);

            // 设置过滤的表单字段
            if (isset($value['form']['filter']) && $value['form']['filter']) {
                $form_filter .= "\"{$value['name']}\",";
            }

            $data['data_form_attr'] .= $this->create_set_field_attr($value, $this->formAttrs, 'form');
            if (isset($value['form']['controlFields']) && $value['form']['controlFields']) {
                $controlFields[$value['name']] = $value['form']['controlFields'];
            }
        }
        // 按钮配置
        if (isset($table['remoteSelectField']) && $table['remoteSelectField'] != '') {
            // 远程搜索字段
            $data['controllerAttr'] .= "// 自定义远程搜索字段
    public \$selectFiled = \"{$table['remoteSelectField']}\";";
        }

        if (isset($table['recycleField']) && $table['recycleField'] != '') {
            // 回收站字段
            $data['controllerAttr'] .= "
    // 自定义回收站字段
    public \$recycleFiled = \"{$table['recycleField']}\";\r\n";
        }
        // 添加withJoinTable
        $withJoinTables = rtrim($withJoinTables, ',');
        $data['controllerAttr'] .= "
    // 设置关联查询
    protected array \$withJoinTable = [{$withJoinTables}];\r\n";

        // 添加快捷搜索
        foreach ($table['quickSearchField'] as $key => $value) {
            $quickSearchField .= "\"{$value}\",";
        }
        $quickSearchField = rtrim($quickSearchField, ",");
        $data['controllerAttr'] .= "
    // 设置快捷搜索字段
    protected string|array \$quickSearchField =  [{$quickSearchField}];\r\n";

        // 添加默认排序
        $defaultSortField = $table['defaultSortField'] ?? '';
        $defaultSortType = $table['defaultSortType'] ?? 'desc';
        if ($defaultSortField) {
            $data['controllerAttr'] .= "
    // 设置默认排序字段
    protected string|array \$defaultSortField = \"{$defaultSortField},{$defaultSortType}\";\r\n";
        }

        // 设置表格字段
        if (isset($table['columnFields']) && $table['columnFields']) {
            $columnFields = "";
            foreach ($table['columnFields'] as $key => $value) {
                $columnFields .= "\"{$value}\",";
            }
            $columnFields = rtrim($columnFields, ',');
            $data['data_table_attr'] .= "
        //设置自定义表格字段顺序和启用
        ->field([$columnFields])";
        }

        // 设置隐藏字段
        if (isset($table['columnHideFields']) && $table['columnHideFields']) {
            $columnHideFields = "";
            foreach ($table['columnHideFields'] as $key => $value) {
                $columnHideFields .= "\"{$value}\",";
            }
            $columnHideFields = rtrim($columnHideFields, ',');
            $data['data_table_attr'] .= "
        //设置隐藏字段
        ->setHideFields([$columnHideFields])";
        }

        // 设置过滤字段
        if (isset($table['columnFilterFields']) && $table['columnFilterFields']) {
            $columnFilterFields = "";
            foreach ($table['columnFilterFields'] as $key => $value) {
                $columnFilterFields .= "\"{$value}\",";
            }
            $columnFilterFields = rtrim($columnFilterFields, ',');
            $data['data_table_attr'] .= "
        //设置过滤字段
        ->setFilterField([$columnFilterFields])";
        }

        // 设置联动字段
        if ($controlFields) {
            // 开始构建 setControlFields 方法调用字符串
            $controlFieldsString = '
        // 设置联动字段
        ->setControlFields([';

            foreach ($controlFields as $mainField => $groups) {
                // 每个主字段开始构建其内部数组
                $innerArrayString = "
            '$mainField' => [";
                foreach ($groups as $group) {
                    $label = $group['label']; // 获取标签值
                    $fields = $group['fields']; // 获取字段列表
                    // 构建每个组的内部数组
                    $fieldNames = [];
                    foreach ($fields as $fieldName) {
                        $fieldNames[] = "'$fieldName'";
                    }
                    $innerArrayString .= "'$label' => [" . implode(', ', $fieldNames) . "],";
                }
                $innerArrayString = rtrim($innerArrayString, ',');
                // 关闭该主字段的内部数组
                $innerArrayString .= "],";

                // 将构造好的内部数组字符串附加到控制字段字符串中
                $controlFieldsString .= $innerArrayString;
            }
            $controlFieldsString = rtrim($controlFieldsString, ',');
            // 关闭外部数组并完成方法调用
            $controlFieldsString .= "
        ])";

            // 将生成的字符串附加到 data_form_attr 中
            $data['data_form_attr'] .= $controlFieldsString;
        }

        // 判断表单选项卡字段
        if (isset($table['tabFields']) && $table['tabFields']) {

            $tabFields = "
        // 设置表单选项卡
        ->setTabFields([
                ";
            foreach ($table['tabFields'] as $key => $value) {
                $tab = "['name' => '{$value['label']}','fields' =>[";

                foreach ($value['fields'] as $k => $val) {
                    $tab .= "'{$val}',";
                }
                $tab = rtrim($tab, ',');
                if ($key == (count($table['tabFields']) - 1)) {
                    $tab .= "]]";
                } else {
                    $tab .= "]],
                ";
                }
                $tabFields .= $tab;
            }
            $tabFields = rtrim($tabFields, ",");
            $tabFields .= "
        ])";

            $data['data_form_attr'] .= $tabFields;

        } elseif (isset($table['formFields']) && $table['formFields']) {
            // 设置表单字段
            $formFields = "";
            foreach ($table['formFields'] as $key => $value) {
                $formFields .= "\"{$value}\",";
            }
            $formFields = rtrim($formFields, ',');
            $data['data_form_attr'] .= "
        //设置自定义表单字段顺序和启用
        ->field([$formFields])";
        }

        // 添加initialize内容
        if ($model_scope_alias_default && $remote) {
            $data['initialize'] .= "\$this->model = new {$data['class_model']}();";
            $data['initialize'] .= "
        // 判断请求控制器方法
        if(\$this->request->action() == \"index\"  && !\$this->request->param(\"select\")){
            // 定义全局的查询范围带有alias
            \$this->model->setGlobalScope(['alias']);
        }";
        } else {
            $data['initialize'] .= "\$this->model = new {$data['class_model']}();";
        }

        // 设置移除字段
        if ($table_filter) {
            $data['data_table_attr'] .= "
        // 设置移除的字段
        ->setFilterField([" . rtrim($table_filter, ',') . "])";
        }
        if ($table_hidden) {
            // 设置隐藏字段
            $data['data_table_attr'] .= "
        // 设置默认隐藏字段
        ->setHideFields([" . rtrim($table_hidden, ',') . "])";
        }
        // 添加表内远程搜索地址
        if ($remote && $setRemoteUrls) {
            $show_table_action = true;
            $urls = "[";
            foreach ($setRemoteUrls as $key => $value) {
                $urls .= "\"{$key}\"=>\"{$value}\",";
            }
            $urls = rtrim($urls, ",");
            $urls .= "]";
            $data['data_table_attr'] .= "    
        ->setRemoteUrls({$urls})";
            $data['data_form_attr'] .= "    
        ->setRemoteUrls({$urls})";
        }
        // 添加按钮Demo
        if ((isset($table['buttonDemo']) && $table['buttonDemo']) || (isset($table['buttons']) && $table['buttons'])) {
            $show_table_action = true;
            $table_buttons = "[";
            // 如果存在自定义选择的按钮
            if (isset($table['buttons']) && $table['buttons']) {
                foreach ($table['buttons'] as $key => $value) {
                    $table_buttons .= "\"{$value}\",";
                }
            } else {
                $table_buttons .= "\"sort\",\"edit\",\"del\",";
            }

            if (isset($table['buttonDemo']) && $table['buttonDemo']) {
                $table_buttons .= "Column::make()->demoButton";
            }
            $table_buttons = rtrim($table_buttons, ",");
            $table_buttons .= "]";
            $data['table_buttons'] = $table_buttons;
            // 按钮配置
            $data['data_table_attr'] .= assembleStub('php/controller/controller_table_operation', $data);
        } else {
            $data['data_table_attr'] .= "
        // 默认操作列
        ->operation()
        ->create();";
        }

        // 重写生成表格方法
        if ($show_table_action || $data['data_table_attr']) {
            $controller_table_action = assembleStub('php/controller/controller_table', $data);
            $data['controller_action'] .= $controller_table_action;
        }
        // 设置移除表单
        if ($form_filter) {
            $data['data_form_attr'] .= "
        // 设置移除的字段
        ->setFilterFields([" . rtrim($form_filter, ',') . "])";
        }


        if ($data['data_form_attr']) {
            $controller_form_action = assembleStub('php/controller/controller_form', $data);
            $data['controller_action'] .= $controller_form_action;
        }


        $res = assembleStub('php/controller/controller', $data);
//        echo $res;
        return $res;
    }

    /**
     * 创建setField内容
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $field
     * @return string
     */
    private function create_set_field_attr($field, $attrs, $type = "table")
    {
        $arr = $field[$type];
        if ($field['comment']) {
            $remarkField = $field['comment'] . ' (' . $field['name'] . ')';
        } else {
            $remarkField = $field['name'];
        }

        // 这里判断表单的designType然后给表单的render
        if ($type == 'form') {
            $designFormTypes = [
                'time', 'datetime', 'date', 'year', 'select', 'selects', 'remoteSelect', 'remoteSelects'
            ];
            // 判断表单的designType
            if ((!isset($arr['render']['render']) || !$arr['render']['render']) && in_array($field['designType'], $designFormTypes)) {
                $arr['render'] = $field['designType'];
            }
        } else {
            // TODO 暂定这些吧
            $designTableTypes = [
                'remoteSelect', 'select', 'date', 'datetime', 'remoteSelects'
            ];
            // 判断表格的designType
            if ((!isset($arr['render']['render']) || !$arr['render']['render']) && in_array($field['designType'], $designTableTypes)) {
                $arr['type'] = $field['designType'];
            }
        }

        $res = "
        // 设置 {$remarkField} 字段自定义配置
        ->setField(\"{$field['name']}\",[";
        $attr_string = '';
        foreach ($attrs as $key => $value) {
            if (isset($arr[$value])) {
                if ($value == "sortable") {
                    $arr[$value] = "custom";
                }
                if (is_string($arr[$value])) {
                    if ($value == 'operator' && ($arr[$value] == 'true' || $arr[$value] == 'false')) {
                        $attr_string .= "\"{$value}\"=>{$arr[$value]},";
                    } else {
                        $attr_string .= "\"{$value}\"=>\"{$arr[$value]}\",";
                    }
                } elseif (is_array($arr[$value]) && $arr[$value]) {
                    $attr_string .= "\"{$value}\"=>[";
                    foreach ($arr[$value] as $k => $val) {
                        $attr_string .= "\"{$val}\",";
                    }
                    $attr_string = rtrim($attr_string, ',');
                    $attr_string .= "],";
                }
            }
        }
        if ($attr_string == "") {
            return "";
        }
        $attr_string = rtrim($attr_string, ',');
        $res .= $attr_string . "])";
        return $res;
    }

    /**
     * 创建模型文件
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $table
     * @param $addon
     * @param $fieldItems
     * @return array|false
     */
    private function create_model_file($table, $addon, $fieldItems)
    {
        $data = [
            'addon_name'                      => $addon['name'],
            'table_name'                      => $table['name'],
            'comment'                         => $table['comment'],
            'class_base_model'                => Str::studly($addon['name'] . 'BaseModel'),
            'scope_plaid'                     => '',
            'scope_appid'                     => '',
            'onBeforeInsert'                  => '',
            // 模型文件
            'class_model'                     => Str::studly($addon['name'] . '_' . $table['name']),
            'field_type'                      => '',
            'field_append'                    => '',
            'belongsTos'                      => '',
            'model_Checkbox'                  => '',
            'model_datetime'                  => '',
            'delete_time_use'                 => '',
            'delete_time_arr'                 => '',
            'model_weigh'                     => '',
            'model_scope_alias_default'       => '',
            'model_scope_alias_default_plaid' => '',
            'model_scope_alias_default_appid' => ''
        ];
        $model_scope_alias_default = [];
        $remote = false;
        $weigh = false;
        $fun_name = "";
        foreach ($fieldItems as $key => $value) {
            if ($value['name'] == 'appid') {
                $data['scope_appid'] = assembleStub('php/model/base_model_scope_appid', $data);
                if ($data['onBeforeInsert']) {
                    $data['onBeforeInsert'] .= "        ";
                }
                $data['onBeforeInsert'] .= '$model->appid = get_appid();' . "\r\n";
            }
            if ($value['name'] == 'plaid') {
                $data['scope_plaid'] = assembleStub('php/model/base_model_scope_plaid', $data);
                if ($data['onBeforeInsert']) {
                    $data['onBeforeInsert'] .= "        ";
                }
                $data['onBeforeInsert'] .= '$model->plaid = get_plaid();' . "\r\n";
            }
            // 包含删除时间
            if ($value['name'] == 'delete_time') {
                $data['delete_time_use'] = 'use think\model\concern\SoftDelete;
                ';
                $data['delete_time_arr'] = '// 配置软删除、启用回收站
    use SoftDelete;
    protected $deleteTime = "delete_time";
    ';
            }
            // 远程搜索
            if ($value['designType'] == 'remoteSelect' || $value['designType'] == 'remoteSelects') {
                $remote = true;
                if (isset($value['remoteConfig']['modelAction']) && $value['remoteConfig']['modelAction'] != '') {
                    $data['fun_name'] = $value['remoteConfig']['modelAction'];
                } else {
                    if(!isset($value['remoteConfig']['table'])){
                        $this->err = "远程字段配置配置中，字段" . $value['name'] . '的远程连接函数名未设置';
                        return false;
                    }
                    $data['fun_name'] = str_replace($this->prefix . $addon['name'] . '_', '', $value['remoteConfig']['table']);
                }
                if ($fun_name == $data['fun_name']) {
                    $this->err = "远程字段配置配置中，字段" . $value['name'] . '的远程连接函数名' . $fun_name . '重复，请设置别名';
                    return false;
                } else {
                    $fun_name = $data['fun_name'];
                }
                $data['belongs_to_model_name'] = Str::studly(str_replace($this->prefix, '', $value['remoteConfig']['table']));
                $data['foreignKey'] = $value['name'];
                $data['localKey'] = $value['remoteConfig']['value'];
                if ($value['designType'] == 'remoteSelect') {
//                    $data['fun_name'] = Str::camel($data['fun_name']. "_". $value['remoteConfig']['label']);
                    // 驼峰
                    $data['fun_name'] = Str::camel($data['fun_name']);

                    $data['belongsTos'] .= assembleStub('php/model/model_belongsTo', $data);
                } else {
                    // 远程多选配置
                    $data['get_attr_fun_name'] = Str::camel('get_' . $data['fun_name'] . "_" . $value['remoteConfig']['label'] . 's_attr');
                    $data['label'] = $value['remoteConfig']['label'];
                    $field_append = $data['fun_name'] . "_" . $value['remoteConfig']['label'] . 's';
                    $data['field_append'] .= "'{$field_append}',";
                    $data['belongsTos'] .= assembleStub('php/model/model_remote_selects', $data);
                }
            }

            if ($value['designType'] == 'checkbox' || @$value['table']['render'] == 'checkbox' || @$value['form']['render'] == 'checkbox') {
                $data['model_Checkbox'] .= assembleStub('php/model/model_Checkbox', ['CheckboxField' => Str::studly($value['name'])]);
            }

            // 判断是否存在平台id和小程序id
            if ($value['name'] == "appid" || $value['name'] == "plaid") {
                $model_scope_alias_default[] = $value['name'];
            }

            if (isset($value['modelType']) && $value['modelType'] != '') {
                $data['field_type'] .= "'{$value['name']}' => '{$value['modelType']}',
        ";
            }
            // 判断是否存在权重字段
            if ($value['name'] == 'weigh') {
                $weigh = true;
            }

            // 判断后缀是否为datetime
            if (substr($value['name'], -strlen("_datetime")) === "_datetime") {
                $data['model_datetime'] .= assembleStub('php/model/model_datetime', ['datetimeField' => Str::studly($value['name'])]);
            }

        }

        if ($weigh) {
            $data['model_weigh'] = assembleStub('php/model/model_weigh', $data);
        }

        // 判断是否有远程连表
        if ($model_scope_alias_default && $remote) {

            foreach ($model_scope_alias_default as $key => $value) {
                if ($value == 'plaid') {
                    $data['model_scope_alias_default_plaid'] .= "if (get_plaid()) {
            \$query->where([\$this->alias . '.plaid' => get_plaid()]);
        }";
                }
                if ($value == 'appid') {
                    $data['model_scope_alias_default_appid'] .= "if (get_appid()) {
            \$query->where([\$this->alias . '.appid' => get_appid()]);
        }";
                }
            }
            $data['model_scope_alias_default'] = assembleStub('php/model/model_scope_alias_default', $data);
        }


        // 基础模型文件
        $base_model = assembleStub('php/model/base_model', $data);
        // 当前模型文件
        $model = assembleStub('php/model/model', $data);

        return ['base_model' => $base_model, 'model' => $model];
    }

    /**
     * 创建页面文件
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $table
     * @param $addon
     * @param $fieldItems
     * @return string
     */
    private function create_page_file($table, $addon, $fieldItems)
    {
        // TODO 基于字段增加内容
        $menuPath = $this->setDefaultValue($table, "menuPath", $table['name']);
        $data = [
            'addon_name'    => $addon['name'],
            'table_name'    => $table['name'],
            'keepaliveName' => Str::studly($menuPath . '_index'),
            'slots'         => '',
            'sdkDemo'       => '',
            'buttonDemo'    => '',
            'import'        => 'ref',
            'dk_table_attr' => ' '
        ];

        // 显示示例demo
        if ($table['pageSdkDemo'] ?? false) {
            $data['sdkDemo'] = assembleStub('vue/page/page_sdk_demo', $data);
        }

        // 设置快捷搜索占位符
        if (isset($table['quickSearchPlaceholder']) && $table['quickSearchPlaceholder']) {
            $data['dk_table_attr'] .= "quick-search-placeholder=\"{$table['quickSearchPlaceholder']}\" ";
        }


        $fieldItem = $fieldItems[0];
        if ($table['tableSlots']) {
            foreach ($table['tableSlots'] as $key => $value) {
                if ($key > 0) {
                    $data['slots'] .= "        ";
                }
                if ($value == 'columnPrepend' || $value == 'columnAppend') {
                    $data['slots'] .= "<template #{$value}><el-table-column prop=\"" . $fieldItem['name'] . "\" label=\"" . $fieldItem['comment'] . "(自定义)\" width=\"180\" /></template>";
                } else {
                    $data['slots'] .= "<template #{$value}><el-button type=\"primary\">按钮示例</el-button></template>";
                }
                if ($key !== count($table['tableSlots']) - 1) {
                    $data['slots'] .= "\r\n";
                }
            }
        }

        $fieldItemSlotCount = 0;
        // 判断回收站
        $have_recycle = false;
        foreach ($fieldItems as $key => $value) {
            $render = $value['table']['render'] ?? '';
            if ($render === 'slot') {
                //使用插槽
                if ($fieldItemSlotCount == 0) {
                    $data['slots'] .= "\r\n";
                }
                if ($data['slots'] != '') {
                    $data['slots'] .= "        ";
                }
                $slotName = $this->setDefaultValue($value['table'], 'slotName', $value['name'] . '_slot');
                $data['slots'] .= "<template #{$slotName}=\"{ row }\">
            <span>{{row." . $value['name'] . "}}</span>
        </template>";
                $data['slots'] .= "\r\n";
                $fieldItemSlotCount++;
            }
            if ($value['name'] == 'delete_time') {
                $have_recycle = true;
            }
        }
        // 判断是否存在回收站
        if (!$have_recycle) {
            // 隐藏回收站按钮
            $data['dk_table_attr'] = " :hide-buttons=\"['recycle']\" ";
        }

        if ($table['buttonDemo'] ?? false) {
            $data['buttonDemo'] = assembleStub('vue/page/page_button', []);
            $data['import'] .= ', onMounted';
        }
        $res = assembleStub('vue/page/page', $data);
        return $res;
    }


    /**
     * 创建路由文件
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $table
     * @param $addon
     * @return string
     */
    private function create_router_file($table, $addon)
    {
        // 多级菜单
        $menuChildren = $table['menuChildren'] ?? false;
        $menuTitle = $this->setDefaultValue($table, "menuTitle", $table['comment']);
        $menuPath = $this->setDefaultValue($table, "menuPath", $table['name']);
        $menuIcon = $this->setDefaultValue($table, "menuIcon", 'Setting');
        $menuWeight = $this->setDefaultValue($table, "menuWeight", 1);
        $menuAddtab = $table['menuAddtab'] ?? true;
        $menuOpen = $table['menuOpen'] ?? true;


        $data = [
            'addon_name'    => $addon['name'],
            'table_name'    => $table['name'],
            'menuPath'      => $menuPath,
            'menuTitle'     => $menuTitle,
            'menuIcon'      => $menuIcon,
            'menuAddtab'    => $menuAddtab,
            'keepaliveName' => Str::studly($menuPath . '_index'),
            'fatherMeta'    => "weight:{$menuWeight}"
        ];
        // 存在多个子菜单
        if ($menuChildren) {
            $data['keepaliveTestName'] = Str::studly($menuPath . "_test");
            $children = assembleStub("vue/router/multiple_children", $data);
            $data['fatherMeta'] = $data['fatherMeta'] . ", title: '{$menuTitle}', open: {$menuOpen}, icon: '{$menuIcon}'";
        } else {
            $children = assembleStub("vue/router/children", $data);
        }
        $data['children'] = $children;
        $res = assembleStub('vue/router/router', $data);
        return $res;
    }

    /**
     * 创建Api文件
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $table
     * @param $addon
     * @return string
     */
    private function create_api_file($table, $addon)
    {
        // 文件路径
        // $file_path = "src/api/" . $table_name . ".js";
        $data = array(
            'addon_name' => $addon['name'],
            'table_name' => $table['name'],
        );
        $res = assembleStub("vue/api", $data);
        return $res;
    }

    /**
     * 生成更新表Sql
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $fieldItems
     * @param $table
     * @return string
     */
    private function update_table($fieldItems, $table, $addon)
    {
        $tableName = $this->prefix . $addon['name'] . '_' . $table['name'];
        // 获取表名称和表备注
        $newSql = $this->create_table($fieldItems, $table, $addon);
        try {
            // 获取表的当前结构
            $oldSql = Db::query("SHOW CREATE TABLE  `{$tableName}`")[0]['Create Table'];
            $updateSqls = SqlDiff::diff($oldSql, $newSql);
        } catch (\Exception $e) {
            return '';
        }
        $sql = '';
        foreach ($updateSqls as $key => $value) {
            $sql .= $value . ';
';
        }
        return $sql;
    }

    /**
     * 生成创建表Sql
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $fieldItems
     * @param $table
     * @return string
     */
    private function create_table($fieldItems, $table, $addon)
    {
        $prefix = config('database.connections.mysql.prefix');
        $tableName = $prefix . $addon['name'] . '_' . $table['name'];
        // 初始化 SQL 字段字符串
        $fieldsSql = [];

        // 遍历设计数据中的每个字段
        foreach ($fieldItems as $field) {
            // 构建字段定义
            $fieldSql = "`{$field['name']}` {$field['type']}";
            if (isset($field['length']) && $field['length'] > 0) {
                if ($field['type'] == 'decimal' && isset($field['precision']) && $field['precision'] > 0) {
                    $fieldSql .= "({$field['length']},{$field['precision']})";
                } else {
                    $fieldSql .= "({$field['length']})";
                }
            }

            if (isset($field['unsigned']) && $field['unsigned']) {
                $fieldSql .= ' unsigned';
            }

            if (isset($field['null']) && !$field['null']) {
                $fieldSql .= ' NOT NULL';
            } else {
                if ($field['defaultType'] === 'NULL') {
                    if ($field['type'] == 'timestamp') {
                        $fieldSql .= " NULL DEFAULT NULL";
                    } else if ($field['type'] != 'text') {
                        $fieldSql .= " DEFAULT NULL";
                    }
                } else {
                    $fieldSql .= ' NULL';
                }
            }

            if ($field['defaultType'] === 'INPUT' && isset($field['default'])) {
                $fieldSql .= " DEFAULT '{$field['default']}'";
            } elseif ($field['defaultType'] === 'EMPTY STRING') {
                $fieldSql .= " DEFAULT ''";
            }

            if (isset($field['autoIncrement']) && $field['autoIncrement']) {
                $fieldSql .= ' AUTO_INCREMENT';
            }

            if (isset($field['comment'])) {
                $fieldSql .= " COMMENT '{$field['comment']}'";
            }

            $fieldsSql[] = $fieldSql;
        }

        // 添加主键
        $primaryKeyFields = array_filter($fieldItems, function ($field) {
            return $field['primaryKey'];
        });

        if (!empty($primaryKeyFields)) {
            $primaryKeyNames = array_column($primaryKeyFields, 'name');
            $fieldsSql[] = "PRIMARY KEY (`" . implode("`, `", $primaryKeyNames) . "`)"; // 支持复合主键
        }
        // 生成 CREATE TABLE 语句
        $sql = "CREATE TABLE `{$tableName}` (\n" . implode(",\n", $fieldsSql) . "\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='{$table['comment']}';";
        return $sql;
    }

    /**
     * 通过表名获取对应字段的注释
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $table
     * @param $field
     * @return false|mixed
     */
    private function getCommentByTableName($table, $field)
    {
        try {
            // 获取当前表的某一个字段的信息
            $columnInfo = Db::query("
                SELECT COLUMN_COMMENT 
                FROM information_schema.COLUMNS 
                WHERE TABLE_SCHEMA = DATABASE() 
                AND TABLE_NAME = ? 
                AND COLUMN_NAME = ?
            ", [$table, $field]);
            return $columnInfo[0]['COLUMN_COMMENT'] ?? false;
        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * 批量执行sql
     * @param $lines
     */
    private function batchSql($lines)
    {
        $templine = '';
        if (!is_array($lines)) {
            $lines = explode("\r\n", $lines);
        }
        foreach ($lines as $line) {
            if (substr($line, 0, 2) == '--' || $line == '' || substr($line, 0, 2) == '/*')
                continue;
            $templine .= $line;
            if (substr(trim($line), -1, 1) == ';') {
                $templine = str_ireplace('INSERT INTO ', 'INSERT IGNORE INTO ', $templine);
                try {
                    Db::execute($templine);
                } catch (\Exception $e) {
                    //Log::write($e->getMessage());
                }
                $templine = '';
            }
        }
    }

    /**
     * 设置默认值
     * Create by :  刘泓宾<514660094@qq.com>
     * @param $array
     * @param $key
     * @param $value
     * @return mixed
     */
    private function setDefaultValue($array, $key, $value)
    {
        return isset($array[$key]) && $array[$key] != '' ? $array[$key] : $value;
    }

    private function getDefaultSwitch($value, $default = false)
    {
        if (isset($value)) {
            return $value == "true";
        } else {
            return $default;
        }
    }

    //    public function getRemoteFileOption($addon_name, $path = 'controller')
//    {
//        if (!$addon_name) {
//            return $this->error("应用名不能为空");
//        }
//        $adminControllerPath = "addons" . DIRECTORY_SEPARATOR . $addon_name . DIRECTORY_SEPARATOR . $path . DIRECTORY_SEPARATOR . "admin/";
//        $directory = app()->getRootPath() . $adminControllerPath;
//        if (!is_dir($directory)) {
//            return $this->error('路径不存在');
//        }
//        $files = scandir($directory);
//        $files = array_diff($files, ['.', '..']);
//        $options = [];
//        foreach ($files as $key => $value) {
//            if (str_ends_with($value, ".php")) {
//                $options[] = [
//                    'label' => $adminControllerPath . $value,
//                    'value' => str_replace('.php', '', $value)
//                ];
//            }
//        }
//        return $this->success('', $options);
//    }

}
